﻿using isky.dapper;
using isky.model;
using isky.webapi;
using isky.webapi.DataAccess;
using isky.webapi.requests;
using log4net;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace isky.logic
{
    public class RFMLogic
    {
        private RFMRecencySql recencySql = null;
        private RFMwebapi rfmWebapi = null;
        public ILog log = null;


       

        public RFMLogic()
        {
            recencySql = new RFMRecencySql();
            rfmWebapi = new RFMwebapi();
            log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        }
        public IEnumerable<dynamic> ListAccount()
        {
            return recencySql.ListAccount();

        }

        /// <summary>
        /// RFM R:近度 F:频度 M:销售
        /// </summary>
        public void RFMTiming()
        {
            try
            {
                log.Info($@"RFM开始调用时间:{DateTime.Now}");
                List<RFMModel> listModelRsult = new List<RFMModel>();
                List<RFMModel> listrenecyModel = RecencyData();
                List<RFMModel> listrequencyModel = RequencyData();
                List<RFMModel> listfmmonetaryModel = FmmonetaryData();
                listModelRsult.AddRange(listrenecyModel);
                listModelRsult.AddRange(listrequencyModel);
                listModelRsult.AddRange(listfmmonetaryModel);
                var result = from r in listModelRsult group r by r.account into g where g.Count() > 1 select g;
               
                List<RFMModel> listModelRsult1 = new List<RFMModel>();
                foreach (var item1 in result)
                {
                    RFMModel model = new RFMModel();
                    foreach (var item in listModelRsult)
                    {
                        if (item.account == item1.Key)
                        {
                            if (item.recency > 0)
                            {
                                model.recency = item.recency;
                            }
                            else if (item.requency > 0)
                            {
                                model.requency = item.requency;
                            }
                            else if (item.monetary > 0)
                            {
                                model.monetary = item.monetary;
                            }
                            model.account = item.account;
                            model.accountid = item.accountid;
                        }
                    }
                    listModelRsult1.Add(model);
                }

                var avgrenecy = listModelRsult.Sum(x => x.recency) / listrenecyModel.Count();
                var avgsumrequency = listModelRsult.Sum(x => x.requency) / listrenecyModel.Count();
                var avgsumfmmonetary = listModelRsult.Sum(x => x.monetary) / listrenecyModel.Count();
                var rulesResult = recencySql.ListRFMClassificationRules().ToList();
                var result1 = listModelRsult1.Select(item =>
                {
                    dynamic dymodel = new ExpandoObject();
                    var rfmIndexer = dymodel as IDictionary<string, Object>;
                    if (item.accountid != Guid.Empty)
                    {
                        rfmIndexer["new_AccountID@odata.bind"] = $"/accounts({item.accountid})";
                    }
                    //dymodel.account = item.account;
                    dymodel.new_rvalue = item.recency;
                    dymodel.new_fvalue = item.requency;
                    dymodel.new_mvalue = item.monetary;
                    dymodel.new_enddate = DateTime.UtcNow;
                    string oprsclass = "";
                    string opfsclass = "";
                    string opmsclass = "";
                    if (item.recency >= avgrenecy)
                    {
                        dymodel.new_rsclassify = "100000000";//高
                        oprsclass = dymodel.new_rsclassify;
                    }
                    else if (item.recency < avgrenecy)
                    {
                        dymodel.new_rsclassify = "100000001";//底
                        oprsclass = dymodel.new_rsclassify;
                    }

                    if (item.requency >= avgsumrequency)
                    {
                        dymodel.new_fsclassify = "100000000";//高
                        opfsclass = dymodel.new_fsclassify;
                    }
                    else if (item.requency < avgsumrequency)
                    {
                        dymodel.new_fsclassify = "100000001";//底
                        opfsclass = dymodel.new_fsclassify;
                    }

                    if (item.monetary >= avgsumfmmonetary)
                    {
                        dymodel.new_msclassify = "100000000";//高
                        opmsclass = dymodel.new_msclassify;
                    }
                    else if (item.monetary < avgsumfmmonetary)
                    {
                        dymodel.new_msclassify = "100000001";//底
                        opmsclass = dymodel.new_msclassify;
                    }

                    foreach (var accountItem in rulesResult)
                    {
                        if (Convert.ToInt32(oprsclass) == Convert.ToInt32(accountItem.new_rsclassify) &&
                            Convert.ToInt32(opfsclass) == Convert.ToInt32(accountItem.new_fsclassify) &&
                            Convert.ToInt32(opmsclass) == Convert.ToInt32(accountItem.new_msclassify))
                        {
                            dymodel.new_rfmmodelname = accountItem.new_name;
                        }
                    }
                    return dymodel;
                }).ToList();
                List<dynamic> accoutevelLResult = null;
                if (result1 != null)
                {
                    accoutevelLResult = result1.Select(item =>
                    {
                        dynamic dyaccountlevel = new ExpandoObject();
                        foreach (var item1 in (IDictionary<string, object>)item)
                        {
                            if (item1.Key == "new_AccountID@odata.bind")
                            {
                                string valie = Convert.ToString(item1.Value);
                                dyaccountlevel.accountid = Guid.Parse(Regex.Replace(valie, @"(.*\()(.*)(\).*)", "$2"));
                            }
                            else if (item1.Key == "new_rfmmodelname")
                            {
                                dyaccountlevel.new_rfmmodelname = item1.Value;
                            }
                        }
                        return dyaccountlevel;
                    }).ToList();
                    if (accoutevelLResult.Count() == 0) { return; }
                }

                CRMEntityDynamic[] entity = new CRMEntityDynamic[] {
                 new CRMEntityDynamic() {
                          entityCollectionName = "new_rfmaccountmodels",
                          httpMethod="POST",
                          entityDynamics=result1.ToList(),
                  },new CRMEntityDynamic() {
                          entityCollectionName = "accounts",
                          primaryKeyName="accountid",
                          httpMethod="PATCH",
                          entityDynamics=accoutevelLResult,
                  }
            };

                CRMBatchResult crmbachResult = rfmWebapi.BatchOperator(entity);
                log.Info($@"RFM结束调用时间:{DateTime.Now}");
            }
            catch (Exception ex)
            {
                log.Error(ex.StackTrace, ex);
            }

             

            // CRMBatchResult rfmaccountmodel = rfmWebapi.CreateBatchRFMaccountmodel(result1.ToArray());

        }

        #region 销售度
        private List<RFMModel> FmmonetaryData()
        {
            try
            {
                List<RFMModel> listfmmonetaryModel = new List<RFMModel>();
                //查询最近销售度版本的天数
                int fmmonetaryDays = recencySql.ListFmmonetaryVersionDay();
                //最近销售度天数所有客户的订单总金额
                var fmmonetaryResult = recencySql.ListFmmonetaryEachSumAmount(fmmonetaryDays);
                if (fmmonetaryResult == null) { return null; }
                log.Info($"{fmmonetaryDays}天内每一个客户的订单总金额：{JsonConvert.SerializeObject(fmmonetaryResult)}");
                fmmonetaryResult.ToList().ForEach(item =>
                {
                    RFMModel fmmonetaryModel = new RFMModel();
                    //最近一次 销售度 规则的 分值,条件符号
                    var fmmdayvalue = recencySql.ListFmmonetaryCriteriaValues();
                    foreach (var fmmdayvalueitem in fmmdayvalue)
                    {
                        //获取近销售度天数天数内每一个客户的订单总金额的数量
                        int fmmcount = fmmonetaryResult.Count();
                        double totalamount = 0;
                        if (fmmcount % 2 > 0)
                        {
                            ////奇数
                            fmmcount = fmmcount - 1;
                            var oddnumber = fmmonetaryResult.ElementAt(fmmcount / 2);
                            foreach (var oddnumberitem in oddnumber)
                            {
                                if (oddnumberitem.Key == "ordersum")
                                {
                                    totalamount = Convert.ToDouble(oddnumberitem.Value);
                                }
                            }
                        }
                        else
                        {

                            var evennumber = fmmonetaryResult.ElementAt(fmmcount / 2);
                            foreach (var evennumberitem in evennumber)
                            {
                                if (evennumberitem.Key == "ordersum")
                                {
                                    totalamount = Convert.ToDouble(evennumberitem.Value);
                                }
                            }
                        }
                        if (fmmdayvalueitem.new_criteria.ToString() == "100000000")
                        {
                            if (Convert.ToDouble(item.ordersum) > totalamount)
                            {
                                fmmonetaryModel.monetary = fmmdayvalueitem.new_value;
                                fmmonetaryModel.account = item.AccountNumber;
                                fmmonetaryModel.accountid = item.accountId;
                                listfmmonetaryModel.Add(fmmonetaryModel);
                            }
                        }
                        else if (fmmdayvalueitem.new_criteria.ToString() == "100000001")//100000000 等于  =
                        {
                            if (Convert.ToDouble(item.ordersum) == totalamount)
                            {
                                fmmonetaryModel.monetary = fmmdayvalueitem.new_value;
                                fmmonetaryModel.account = item.AccountNumber;
                                fmmonetaryModel.accountid = item.accountId;
                                listfmmonetaryModel.Add(fmmonetaryModel);
                            }
                        }
                        else if (fmmdayvalueitem.new_criteria.ToString() == "100000002") //100000000 等于 <
                        {
                            if (Convert.ToDouble(item.ordersum) < totalamount)
                            {
                                fmmonetaryModel.monetary = fmmdayvalueitem.new_value;
                                fmmonetaryModel.account = item.AccountNumber;
                                fmmonetaryModel.accountid = item.accountId;
                                listfmmonetaryModel.Add(fmmonetaryModel);
                            }
                        }
                    }

                });
                return listfmmonetaryModel;
            }
            catch (Exception ex)
            {

                throw ex;
            }
           
        }
        #endregion

        #region 频度
        private List<RFMModel> RequencyData()
        {
            try
            {
                List<RFMModel> listrrequencyModel = new List<RFMModel>();
                //最近频度版本的天数
                int versionday = recencySql.ListFrequencyVersionDay();
                //最近版本天数所有每个客户订单的总数
                var frequencyResult = recencySql.ListOrderCount(versionday);
                if (frequencyResult == null) { return null; }
                frequencyResult.ToList().ForEach(item =>
                {
                    RFMModel frequencyModel = new RFMModel();
                    //最近一次 频度 规则的 分值,条件符号
                    var dayvaluesResult = recencySql.ListFrequencyCriteriaValues();
                    foreach (var dayvaluesItems in dayvaluesResult)
                    {
                        //最近版本天数所有客户订单的总数
                        int ordercount = recencySql.ListOrderSum(versionday);
                        //最近版本天数所有客户总数
                        int accountcount = recencySql.GetAccountCount(versionday);
                        double total = Math.Round(Convert.ToDouble(ordercount) / Convert.ToDouble(accountcount), MidpointRounding.AwayFromZero);
                        log.Info($"F:{versionday}所有客户订单的总数{ordercount}、所有客户总数{accountcount}、平均值{total}");
                        //100000000 等于  >
                        if (dayvaluesItems.new_criteria.ToString() == "100000000")
                        {
                            if (item.ordercount > total)
                            {
                                frequencyModel.requency = dayvaluesItems.new_value;
                                frequencyModel.account = item.AccountNumber;
                                frequencyModel.accountid = item.accountId;
                                listrrequencyModel.Add(frequencyModel);
                            }
                        }
                        else if (dayvaluesItems.new_criteria.ToString() == "100000001")//100000000 等于  =
                        {
                            if (item.ordercount == total)
                            {
                                frequencyModel.requency = dayvaluesItems.new_value;
                                frequencyModel.account = item.AccountNumber;
                                frequencyModel.accountid = item.accountId;
                                listrrequencyModel.Add(frequencyModel);
                            }
                        }
                        else if (dayvaluesItems.new_criteria.ToString() == "100000002") //100000000 等于 <
                        {
                            if (item.ordercount < total)
                            {
                                frequencyModel.requency = dayvaluesItems.new_value;
                                frequencyModel.account = item.AccountNumber;
                                frequencyModel.accountid = item.accountId;
                                listrrequencyModel.Add(frequencyModel);
                            }
                        }
                    }
                });
                return listrrequencyModel;
            }
            catch (Exception ex)
            {

                throw ex;
            }

           
        }
        #endregion

        #region 近度
        private List<RFMModel> RecencyData()
        {
            try
            {
                List<RFMModel> listRecency = new List<RFMModel>();
                List<dynamic> listLog1 = new List<dynamic>();
                List<string> listLog2 = new List<string>();
                int recencyday = recencySql.ListRFMRecencyDaysnum();
                var orderResult = recencySql.ListOrderNumber(recencyday);
                if (orderResult == null) return null;
                orderResult.ToList().ForEach(item =>
                {
                    RFMModel model = new RFMModel();
                    // 查询最近一次 近度 规则的 天数和分值
                    var recencyResult = recencySql.ListRFMRecencyDayValues();
                    foreach (var reccitem in recencyResult)
                    {
                       
                        //查询订单编号最近天数
                        var result = recencySql.GetOrderRecenddays(Convert.ToInt32(reccitem.new_DaysNum), item.ordernumber);
                        if (result > 0)
                         {
                            //listLog.add
                            log.Info($"R：{item.accountnumber}最近一次订单是在{result}天内");
                            if (result <= Convert.ToInt32(reccitem.new_DaysNum))
                            {
                                model.account = item.accountnumber;
                                model.accountid = item.accountId;
                                model.recency = reccitem.new_Value;
                                listRecency.Add(model);
                                break;
                            }
                        }

                    }
                });
                return listRecency;
            }
            catch (Exception ex)
            {

                throw ex;
            }
            
        }
        #endregion
    }

}

